package com.lianliankan.llkan;

import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.BitmapDrawable;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.example.llkan.R;

/*  ****备注****
 1、横向的为X，纵向的为Y  
 */
public class GameView extends View {
	public static int score = 0;
	private int comboTime = 1000;
	private final int COMBOSCORE = 5;
	private int combo = 0;
	private Boolean isCombo = false;
	private Boolean isProp = false;
	private Paint paint = new Paint();
	private int row = 10;
	private int cols = 7;
	private int width;
	private int height;
	private int iconWidth;
	private int iconHeight;
	private int curX = 0;
	private int curY = 0;
	private int lastX = 0;
	private int lastY = 0;
	private int picCount = 8;
	private int bombTotal = 0;
	private int choose = 0;
	private Point line[] = new Point[3];
	private Boolean isSame = false;
	private Bitmap[] icons = new Bitmap[picCount];
	private int[][] map = new int[row][cols];

	private Bitmap linkLineh = ((BitmapDrawable) this.getContext()
			.getResources().getDrawable(R.drawable.linklineh)).getBitmap();
	private Bitmap linkLines = ((BitmapDrawable) this.getContext()
			.getResources().getDrawable(R.drawable.linklines)).getBitmap();

	public GameView(Context context, AttributeSet attrs) {
		super(context, attrs);
		score = 0;

		loadIcons();
		randomicons();
		// TODO Auto-generated constructor stub
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		width = this.getWidth() / row;
		height = this.getHeight() / cols;
		// 获取游戏区域宽度高度，计算横着放8个一张图片需要多大，高同理，绘图时设置图片大小
		paint.setTextSize(20);
		canvas.drawText(String.valueOf(score), 400, 20, paint);
		iconWidth = ((BitmapDrawable) this.getContext().getResources()
				.getDrawable(R.drawable.p1)).getBitmap().getWidth();
		iconHeight = ((BitmapDrawable) this.getContext().getResources()
				.getDrawable(R.drawable.p1)).getBitmap().getHeight();
		RectF rDst = null;
		for (int x = 1; x < row - 1; x++) {
			for (int y = 1; y < cols - 1; y++) {
				if (map[x][y] != -1) {

					if (choose > 0 && curX == x && curY == y) {
						narrowPic(canvas);
					} else {
						rDst = new RectF(x * width, y * height, x * width
								+ iconWidth + 3, y * height + iconHeight + 3);
						canvas.drawBitmap(icons[map[x][y]], null, rDst, paint);
					}
				}
			}
		}

		drawLine(canvas);

	}

	private void narrowPic(Canvas canvas) {
		int newWidth = 44;
		int newHeight = 44;
		RectF rDst = new RectF(curX * width + 2, curY * height + 2, curX
				* width + newWidth + 4, curY * height + newHeight + 4);

		int width = icons[map[curX][curY]].getWidth();
		int height = icons[map[curX][curY]].getHeight();

		float scaleWidth = ((float) newWidth) / width;
		float scaleHeight = ((float) newHeight) / height;

		Matrix matrix = new Matrix();
		matrix.postScale(scaleWidth, scaleHeight);
		Bitmap bitmap = null;
		Bitmap resizedBitmap = bitmap.createBitmap(icons[map[curX][curY]], 0,
				0, width, height, matrix, true);

		canvas.drawBitmap(resizedBitmap, null, rDst, paint);
	}

	// 点击事件
	public boolean onTouchEvent(MotionEvent event) {
		if (event.getAction() != MotionEvent.ACTION_DOWN)
			return super.onTouchEvent(event);
		lastX = curX;
		lastY = curY;
		if (event.getX() / width >= row
				|| event.getY() / height >= cols
				|| map[(int) (event.getX() / width)][(int) (event.getY() / height)] == -1) {
			return false;
		}
		choose = choose == 0 ? 1 : choose;
		curX = (int) (event.getX() / width);
		curY = (int) (event.getY() / height);
		if (map[curX][curY] == map[lastX][lastY]) {
			Point point = new Point();
			point = assignPoint(curX, curY, lastX, lastY);
			point = valueComparison(point);
			if (removeIcon(point)) {
				choose = 2;
				map[point.P1.X][point.P1.Y] = map[point.P2.X][point.P2.Y] = -1;
				comboTimeHandler.removeCallbacks(comboThread);
				if (!isCombo) {
					score += 600;
					combo = 1;
					isCombo = true;
				} else {
					score = score + (comboTime * COMBOSCORE * combo);
					combo++;
				}
				comboTime = 1000;
				comboTimeHandler.post(comboThread);
				isSame = true;
			}
			if (isRemoveAll()) {
				choose = 0;
				randomicons();
			}
		}
		invalidate();
		return true;
	}

	// 连击线程
	Handler comboTimeHandler = new Handler();
	Runnable comboThread = new Runnable() {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			if (comboTime == 0) {
				comboTimeHandler.removeCallbacks(comboThread);
				isCombo = false;
			} else {
				comboTime = comboTime - 10;
				comboTimeHandler.postDelayed(comboThread, 10);
			}
		}
	};

	// 判断是否都消除完了
	private Boolean isRemoveAll() {
		for (int y = 1; y < cols - 1; y++) {
			for (int x = 1; x < row - 1; x++) {
				if (map[x][y] != -1)
					return false;
			}
		}
		return true;
	}

	// 判断是否可消除点击图标
	private Boolean removeIcon(Point point) {
		Point tempPoint = new Point();
		Point tempPoint2 = new Point();
		Point tempPoint3 = new Point();
		line = new Point[3];
		if ((onLineX(point.P1.X, point.P2.X) || onLineY(point.P1.Y, point.P2.Y))) {// 两点同一条直线
			if (hasLine(point)) {// 如果两点可连接直接返回
				line[0] = point;
				return true;
			}
			if (isSurround(point)) {// 判断是否有一点被包围
				return false;
			}

			if (onLineX(point.P1.X, point.P2.X)) {
				for (Integer i = 0; i < row; i++) {
					if (!isEmpty(i, point.P1.Y) || !isEmpty(i, point.P2.Y)) {// 判断转角两点是否有图片，有则继续循环
						continue;
					}
					tempPoint = assignPoint(i, point.P1.Y, point.P1.X,
							point.P1.Y);
					tempPoint2 = assignPoint(i, point.P2.Y, point.P2.X,
							point.P2.Y);
					if (hasLine(tempPoint) && hasLine(tempPoint2)) {
						tempPoint3 = assignPoint(i, point.P1.Y, i, point.P2.Y);
						if (hasLine(tempPoint3)) {
							line[0] = tempPoint;
							line[1] = tempPoint2;
							line[2] = tempPoint3;
							return true;
						}
					}
				}
			} else if (onLineY(point.P1.Y, point.P2.Y)) {
				for (Integer i = 0; i < cols; i++) {
					if (!isEmpty(point.P1.X, i) || !isEmpty(point.P2.X, i)) {// 判断转角两点是否有图片，有则继续循环
						continue;
					}
					tempPoint = assignPoint(point.P1.X, i, point.P1.X,
							point.P1.Y);
					tempPoint2 = assignPoint(point.P2.X, i, point.P2.X,
							point.P2.Y);
					if (hasLine(tempPoint) && hasLine(tempPoint2)) {
						tempPoint3 = assignPoint(point.P1.X, i, point.P2.X, i);
						if (hasLine(tempPoint3)) {
							line[0] = tempPoint;
							line[1] = tempPoint2;
							line[2] = tempPoint3;
							return true;
						}
					}
				}
			}
		} else {// 两点不同直线
			if (isSurround(point)) {
				return false;
			}
			// 横向扫描是否存在可连接路径
			for (Integer i = 0; i < row; i++) {
				tempPoint = assignPoint(i, point.P1.Y, point.P1.X, point.P1.Y);
				tempPoint2 = assignPoint(i, point.P2.Y, point.P2.X, point.P2.Y);
				if (equal(tempPoint.P1, tempPoint.P2)) {
					if (!isEmpty(tempPoint2.P1.X, tempPoint2.P1.Y)) {
						continue;
					}
					tempPoint3 = assignPoint(i, point.P1.Y, i, point.P2.Y);
					if (hasLine(tempPoint3) && hasLine(tempPoint2)) {
						line[0] = tempPoint;
						line[1] = tempPoint2;
						line[2] = tempPoint3;
						return true;
					}
				} else if (equal(tempPoint2.P1, tempPoint2.P2)) {
					if (!isEmpty(tempPoint.P1.X, tempPoint.P1.Y)) {
						continue;
					}
					tempPoint3 = assignPoint(i, point.P1.Y, i, point.P2.Y);
					if (hasLine(tempPoint) && hasLine(tempPoint3)) {
						line[0] = tempPoint;
						line[1] = tempPoint2;
						line[2] = tempPoint3;
						return true;
					}
				}
				if (!isEmpty(i, point.P1.Y) || !isEmpty(i, point.P2.Y)) {
					continue;
				}
				if (hasLine(tempPoint) && hasLine(tempPoint2)) {
					tempPoint3 = assignPoint(i, point.P1.Y, i, point.P2.Y);
					if (hasLine(tempPoint3)) {
						line[0] = tempPoint;
						line[1] = tempPoint2;
						line[2] = tempPoint3;
						return true;
					}
				}
			}
			// 纵向扫描是否可连接路径
			for (Integer i = 0; i < cols; i++) {

				tempPoint = assignPoint(point.P1.X, i, point.P1.X, point.P1.Y);
				tempPoint2 = assignPoint(point.P2.X, i, point.P2.X, point.P2.Y);
				if (equal(tempPoint.P1, tempPoint.P2)) {
					if (!isEmpty(tempPoint2.P1.X, tempPoint2.P1.Y)) {
						continue;
					}
					tempPoint3 = assignPoint(point.P1.X, i, point.P2.X, i);
					if (hasLine(tempPoint3) && hasLine(tempPoint2)) {
						line[0] = tempPoint;
						line[1] = tempPoint2;
						line[2] = tempPoint3;
						return true;
					}
				} else if (equal(tempPoint2.P1, tempPoint2.P2)) {
					if (!isEmpty(tempPoint.P1.X, tempPoint.P1.Y)) {
						continue;
					}
					tempPoint3 = assignPoint(point.P1.X, i, point.P2.X, i);
					if (hasLine(tempPoint) && hasLine(tempPoint3)) {
						line[0] = tempPoint;
						line[1] = tempPoint2;
						line[2] = tempPoint3;
						return true;
					}
				}
				if (!isEmpty(point.P1.X, i) || !isEmpty(point.P2.X, i)) {
					continue;
				}
				if (hasLine(tempPoint) && hasLine(tempPoint2)) {
					tempPoint3 = assignPoint(point.P1.X, i, point.P2.X, i);
					if (hasLine(tempPoint3)) {
						line[0] = tempPoint;
						line[1] = tempPoint2;
						line[2] = tempPoint3;
						return true;
					}
				}
			}
		}
		return false;
	}

	// 判断点击的两个点有没有被全包围的
	private Boolean isSurround(Point point) {
		if ((!isEmpty(point.P1.X - 1, point.P1.Y)
				&& !isEmpty(point.P1.X + 1, point.P1.Y)
				&& !isEmpty(point.P1.X, point.P1.Y + 1) && !isEmpty(point.P1.X,
					point.P1.Y - 1))
				|| (!isEmpty(point.P2.X - 1, point.P2.Y)
						&& !isEmpty(point.P2.X + 1, point.P2.Y)
						&& !isEmpty(point.P2.X, point.P2.Y + 1) && !isEmpty(
							point.P2.X, point.P2.Y - 1))) {
			return true;
		}
		return false;
	}

	// 给point赋值
	private Point assignPoint(int p1_X, int p1_Y, int p2_X, int p2_Y) {
		Point point = new Point();
		point.P1.X = p1_X;
		point.P1.Y = p1_Y;
		point.P2.X = p2_X;
		point.P2.Y = p2_Y;
		return point;

	}

	// 选中时画需要的框框
	private void drawLine(Canvas canvas) {
		RectF rDst = null;
		removeCallbacks(lineThread);
		if (choose == 2 && isSame) {
			int picCenterW = width / 2 - 12;
			int picCenterH = height / 2 - 12;

			for (int i = 0; i < line.length; i++) {
				if (line[i] == null)
					continue;
				if (equal(line[i].P1, line[i].P2)) {
					line[i] = null;
				}

			}
			for (int i = 0; i < line.length; i++) {
				if (line[i] == null)
					continue;
				int lineWidth = 0;
				int lineHeight = 0;
				int x1 = line[i].P1.X;
				int y1 = line[i].P1.Y;
				int x2 = line[i].P2.X;
				int y2 = line[i].P2.Y;
				Bitmap bitmap = null;
				Bitmap resizedBitmap = null;
				if (onLineX(x1, x2)) {
					lineWidth = linkLines.getWidth();
					resizedBitmap = bitmap.createBitmap(linkLines, 0, 0,
							lineWidth, Math.abs(y1 - y2) * height);
					if (y1 > y2) {
						int temp;
						temp = y1;
						y1 = y2;
						y2 = temp;
					}
				} else if (onLineY(y1, y2)) {
					lineHeight = linkLineh.getHeight();
					resizedBitmap = bitmap.createBitmap(linkLineh, 0, 0,
							Math.abs(x1 - x2) * width, lineHeight);
					if (x1 > x2) {
						int temp;
						temp = x1;
						x1 = x2;
						x2 = temp;
					}
				}
				rDst = new RectF(x1 * width + picCenterW, y1 * height
						+ picCenterH, x2 * width + picCenterW + lineWidth, y2
						* height + picCenterH + lineHeight);
				canvas.drawBitmap(resizedBitmap, null, rDst, paint);

			}
			choose = 0;
			isSame = false;

			comboTimeHandler.postDelayed(lineThread, 300);
		}
	}

	Runnable lineThread = new Runnable() {

		@Override
		public void run() {
			invalidate();
			removeCallbacks(lineThread);
		}

	};

	// 将图标加载入Bitmap一个变量中
	private void loadIcons() {
		for (int i = 0; i < picCount; i++) {
			icons[i] = ((BitmapDrawable) this.getContext().getResources()
					.getDrawable(R.drawable.p1 + i)).getBitmap();
		}
	}

	// 随机打乱图标顺序
	private void randomicons() {
		int pic = 0;
		for (int x = 0; x < row; x++) {
			map[x][0] = -1;
			map[x][cols - 1] = -1;
		}
		for (int y = 0; y < cols; y++) {
			map[0][y] = -1;
			map[row - 1][y] = -1;
		}
		for (int i = 1; i < cols - 1; i++) {
			for (int j = 1; j < row - 1; j += 2) {
				map[j][i] = map[j + 1][i] = pic++;
				if (pic == picCount)
					pic = 0;
			}
		}
		int tmpV, tmpX, tmpY;
		Random random = new Random();
		for (int y = 1; y < cols - 1; y++) {
			for (int x = 1; x < row - 1; x++) {
				tmpV = map[x][y];
				tmpX = random.nextInt(row - 2) + 1;
				tmpY = random.nextInt(cols - 2) + 1;
				map[x][y] = map[tmpX][tmpY];
				map[tmpX][tmpY] = tmpV;
			}
		}
	}

	// 判断是否在X轴上同直线
	private Boolean onLineX(Object CX, Object LX) {
		return CX == LX;
	}

	// 判断是否在Y轴上同直线
	private Boolean onLineY(Object CY, Object LY) {
		return CY == LY;
	}

	// 判断是否存在可连接的线
	private Boolean hasLine(Point point) {
		if (point.P1.X == point.P2.X && point.P1.Y == point.P2.Y)
			return false;
		if (onLineX(point.P1.X, point.P2.X)) {
			Integer i = point.P1.Y < point.P2.Y ? point.P1.Y : point.P2.Y;
			Integer Max = point.P1.Y < point.P2.Y ? point.P2.Y : point.P1.Y;
			i += 1;
			for (; i < Max; i++) {
				if (!isEmpty(point.P1.X, i)) {
					return false;
				}
			}
		} else if (onLineY(point.P1.Y, point.P2.Y)) {
			Integer i = point.P1.X < point.P2.X ? point.P1.X : point.P2.X;
			Integer Max = point.P1.X < point.P2.X ? point.P2.X : point.P1.X;
			i += 1;
			for (; i < Max; i++) {
				if (!isEmpty(i, point.P1.Y)) {
					return false;
				}
			}
		}
		return true;
	}

	// 判断一个点是否为空
	private Boolean isEmpty(Integer x, Integer y) {
		if (map[x][y] == -1) {
			return true;
		} else {
			return false;
		}
	}

	private Boolean equal(Point.P P1, Point.P P2) {
		return ((P1.X == P2.X) && (P1.Y == P2.Y));
	}

	// 交换两点使p1尽可能在p2的左边和上边
	private Point valueComparison(Point point) {
		Point.P temp;
		if (point.P1.X > point.P2.X) {
			temp = point.P1;
			point.P1 = point.P2;
			point.P2 = temp;
		} else if (point.P1.X == point.P2.X) {
			if (point.P1.Y > point.P2.Y) {
				temp = point.P1;
				point.P1 = point.P2;
				point.P2 = temp;
			}
		}
		return point;
	}

	// 定义一个点的类
	class Point {
		public P P1 = new P();
		public P P2 = new P();

		class P {
			public Integer X;
			public Integer Y;
		}
	}

}
